#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "net.h"
#include "util.h"

/*debug printf*/
#define TAG_NETTEST                        "NETTEST"

#define DebugPrint_NetTest(fmt,...)        printWithTimestamp(TAG_NETTEST,DEBUG_LEVEL_INFO, fmt, ##__VA_ARGS__) // 带时间戳
#define DebugPrint_NetTest_DEG(fmt,...)    printWithTimestamp(TAG_NETTEST,DEBUG_LEVEL_DEBUG, fmt, ##__VA_ARGS__) // 带时间戳
// 定义用于测试的事件位
#define TEST_EVENT_CONNECTING (1 << NET_EVENT_CONNECTING)
#define TEST_EVENT_CONNECTED (1 << NET_EVENT_CONNECTED)
#define TEST_EVENT_CONNECT_TIMEOUT (1 << NET_EVENT_CONNECT_TIMEOUT)


typedef enum {
    EventType_UNKNOWN = 0, // 默认值
    EventType_NetEvent,
    EventType_NetReport
} EventType;

typedef struct {
    EventType eventType;
    NetEvent netEvent;
    NetReport netReport;
} Event_t;

Event_t xEvent;

// 全局变量，用于存储从用户回调函数接收的消息类型
volatile NetMsgType receivedMsgType = NET_MSG_INITIALIZED;

EventGroupHandle_t xEventGroup = NULL;

// 用户回调函数
void vUserEventHook(NetEvent *event, NetReport *report) {
	DebugPrint_NetTest("vUserEventHook: type=%d, message=%p\n", event->type, event->message);
    xEvent.eventType = EventType_NetEvent;
    xEvent.netEvent = *event;
    xEvent.netReport = *report;

    DebugPrint_NetTest("vUserEventHook: xEvent.eventType=%d \n", xEvent.eventType);
    DebugPrint_NetTest("vUserEventHook: xEvent.netEvent addr=%p, type=%d, message addr=%p\n", 
                        &xEvent.netEvent, 
                        xEvent.netEvent.type,
                        xEvent.netEvent.message);

    // 根据事件类型更新全局变量
    if (event->type == NET_EVENT_CONNECTING) {
        receivedMsgType = report->netMsgType;
        xEventGroupSetBits(xEventGroup, TEST_EVENT_CONNECTING);
    } else if (event->type == NET_EVENT_CONNECTED) {
        receivedMsgType = report->netMsgType;
        xEventGroupSetBits(xEventGroup, TEST_EVENT_CONNECTED);
    } else if (event->type == NET_EVENT_CONNECT_TIMEOUT) {
        receivedMsgType = report->netMsgType;
        xEventGroupSetBits(xEventGroup, TEST_EVENT_CONNECT_TIMEOUT);
    }
}

// 测试任务
void vTestNetTask(void *pvParameters) {
    // 创建事件组
    xEventGroup = xEventGroupCreate();
    if (xEventGroup == NULL) {
        // 事件组创建失败处理
        while (1) {}
    }

    // 注册用户回调函数
    net.userEventHook = vUserEventHook;

    // 初始化 net 模块
    net.Init();

    // 测试 NET_EVENT_CONNECTING 事件
    NetEvent event;
    event.type = NET_EVENT_CONNECTING;
	event.message = NULL; // 假设 message 为 NULL	
    // 发送事件到事件队列
    net.Handle(&event);

    // 等待用户回调中收到 NET_MSG_CONNECTED 消息
	EventBits_t uxBits = 0;

	while (1)
	{
		/* code */
		uxBits |= xEventGroupWaitBits(
								xEventGroup, 
								TEST_EVENT_CONNECTED|TEST_EVENT_CONNECT_TIMEOUT|TEST_EVENT_CONNECTING,
								pdTRUE, 
								pdFALSE, 
								portMAX_DELAY);
		if(uxBits & TEST_EVENT_CONNECTED){
            DebugPrint_NetTest("Test passed: NET_MSG_CONNECTED received.\n");
			// 测试带有 message 的 NET_EVENT_CONNECTING 事件
			event.type = NET_EVENT_CONNECTING;
			event.message = (void *)1000; // 假设 message 为 1000ms 超时时间
			// 发送事件到事件队列
			net.Handle(&event);
			uxBits &= ~TEST_EVENT_CONNECTED;
			continue;
        } else if(uxBits & TEST_EVENT_CONNECT_TIMEOUT) {
            DebugPrint_NetTest("Test failed: Expected NET_MSG_CONNECTED, got %d.\n", receivedMsgType);
			uxBits &= ~TEST_EVENT_CONNECT_TIMEOUT;
			break;
        }
		vTaskDelay(10 / portTICK_PERIOD_MS);
	}
	// 清理资源
    DebugPrint_NetTest("Test end.\n");
    vEventGroupDelete(xEventGroup);
    net.Deinit();
    vTaskDelete(NULL);
}

void net_test(void) {
    // 创建测试任务
    xTaskCreate(vTestNetTask, "TestNet", configMINIMAL_STACK_SIZE * 2, NULL, 2, NULL);

    // 启动调度器
    vTaskStartScheduler();

    // 主循环永远不会返回
    for (;;);
}